package org.stvd.controller.common;
 
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.stvd.common.SecurityUserHolder;
import org.stvd.common.aspectj.lang.annotation.Log;
import org.stvd.common.aspectj.lang.enums.BusinessType;
import org.stvd.common.dto.UploadDTO;
import org.stvd.common.utils.FileUtil;
import org.stvd.common.utils.InterfaceResult;
import org.stvd.controller.BaseController;
import org.stvd.core.util.DateUtil;
import org.stvd.core.util.IdWorker;
import org.stvd.core.util.StringUtil;
import org.stvd.entities.common.AffixUpload;
import org.stvd.service.common.AffixUploadService;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.vod.model.v20170321.CreateUploadVideoResponse;
import com.aliyuncs.vod.model.v20170321.GetPlayInfoResponse;
import com.aliyuncs.vod.model.v20170321.GetVideoInfoResponse;
import com.aliyuncs.vod.model.v20170321.RefreshUploadVideoResponse;

/**
 * @Title: AliyunUploadController
 * @Description: 阿里云上传控制类
 * @author houzx
 * @date 2020年8月5日
 */
@Controller
@RequestMapping(value = "/common/aliyun")
public class AliyunUploadController extends BaseController{
 
    @Autowired
    private AffixUploadService affixUploadService;
    
    private String tmpURL = "/common/aliyun/";
    
    DefaultAcsClient client = AliyunCommonUtil.initClient();
    
    /**
     * 附件上传
     * @param req 上传请求
     * @return
     */
    @Log(title = "上传图片", businessType = BusinessType.OTHER)
    @PostMapping(value = "uploadimage")
    @ResponseBody
    public InterfaceResult<UploadDTO> uploadImage(HttpServletRequest req){
        String fileRelativePath = "image/";
        return handleFileUpload(req, fileRelativePath);
    }
    
    @Log(title = "上传文件", businessType = BusinessType.OTHER)
    @PostMapping(value = "uploadfile")
    @ResponseBody
    public InterfaceResult<UploadDTO> uploadFile(HttpServletRequest req){
        String fileRelativePath = "file/";
        return handleFileUpload(req, fileRelativePath);
    }
    
    private InterfaceResult<UploadDTO> handleFileUpload(HttpServletRequest req, String fileRelativePath) {
        InterfaceResult<UploadDTO> result = new InterfaceResult<UploadDTO>();
        MultipartHttpServletRequest mReq  =  null;
        MultipartFile file = null;
        // 原始文件名 UEDITOR创建页面元素时的alt和title属性
        String fileName = "";
        
        try {
            mReq = (MultipartHttpServletRequest)req;
            // 取得上传文件的ID
            file = mReq.getFile("file");
            fileName = file.getOriginalFilename();
            
            if(StringUtil.isEmpty(fileName)){
                result.setError("上传取消，取消原因：文件名为空！");
                return result;
            }
            //上传到OSS
            fileRelativePath += FileUtil.reName(fileName);
            AliyunCommonUtil.uploadFileAliyun(file.getInputStream(), fileRelativePath);
            
            Long sourceId = IdWorker.getInstance().nextId();
            String fileUrl = AliyunCommonUtil.httpPath +"/"+ fileRelativePath;
            
            //存储阿里云资源信息到本地库
            AffixUpload affixUpload = new AffixUpload();
            affixUpload.setId(sourceId);
            affixUpload.setName(fileName);
            affixUpload.setLocalUrl(fileUrl);
            affixUpload.setExtension(getFileExtension(fileName));
            affixUpload.setSize(file.getSize());
            affixUpload.setStatus("0");
            affixUpload.setCreateUser(SecurityUserHolder.getCurrentUserid());
            affixUpload.setCreateTime(DateUtil.getSystemDate());
            affixUpload.setModifyTime(DateUtil.getSystemDate());
            affixUploadService.insert(affixUpload);
            
            UploadDTO uploadDTO = new UploadDTO();
            uploadDTO.setFileId(sourceId.toString());
            uploadDTO.setFileName(fileName);
            uploadDTO.setFilePath(fileUrl);
            uploadDTO.setFileExtension(affixUpload.getExtension());
            uploadDTO.setFileSize(affixUpload.getSize().toString());
            result.setMsg("上传成功");
            result.setResult(uploadDTO);
        }catch (Exception e) {
            System.out.println(e.getMessage());
            result.setError("上传失败! 失败原因："+e.getMessage());
        }
        return result;
    }

    
    /**
     * @Description: 视频点播上传
     * @param req
     * @return
     */
    @Log(title = "上传音视频", businessType = BusinessType.OTHER)
    @PostMapping(value = "uploadvod")
    @ResponseBody
    public InterfaceResult<Map<String, Object>> uploadVod(HttpServletRequest req){
        InterfaceResult<Map<String, Object>> result = new InterfaceResult<Map<String,Object>>();
        Map<String, Object> resultMap = new HashMap<String, Object>();
        String videoId = req.getParameter("videoId");
        String fileName = req.getParameter("fileName");
        String fileSize = req.getParameter("fileSize");
        if(StringUtil.isEmpty(videoId) || StringUtil.isEmpty(fileName) || StringUtil.isEmpty(fileSize)) {
            result.setError("参数异常！");
            return result;
        }
        String fileCoverUrl = "";
        try {
            do {
                GetVideoInfoResponse res = AliyunCommonUtil.getVideoInfo(client, videoId);
                fileCoverUrl = res.getVideo().getCoverURL();
            } while (StringUtil.isEmpty(fileCoverUrl));
        } catch (Exception e) {
            e.printStackTrace();
        }
        //TODO 存储阿里云资源信息到本地库
        //...
        resultMap.put("fileCoverUrl", fileCoverUrl);
        result.setResult(resultMap);
        result.setMsg("保存成功！");
        return result;
    }
    
    /**
     * @Description: 删除视频
     * @param videoId
     * @return
     */
    @Log(title = "删除音视频", businessType = BusinessType.OTHER)
    @PostMapping(value = "removevod")
    @ResponseBody
    public InterfaceResult<Map<String, Object>> DeleteUploadVod(@RequestParam("videoId") String videoId) {
        InterfaceResult<Map<String, Object>> result = new InterfaceResult<Map<String,Object>>();
        try {
            AliyunCommonUtil.deleteVideo(client, videoId);
            result.setMsg("删除成功");
        } catch (Exception e) {
            System.out.println(e.getMessage());
            result.setError("删除失败,失败原因："+e.getMessage());
        }
        return result;
    }
    
    /**
     * @Description: 视频播放
     * @param videoId
     * @return
     */
    @GetMapping(value = "playvod/{videoId}")
    public String playVod(@PathVariable String videoId) {
        try {
            GetPlayInfoResponse response = AliyunCommonUtil.getPlayInfo(client, videoId);
            List<GetPlayInfoResponse.PlayInfo> playInfoList = response.getPlayInfoList();
            // 播放地址
            if(playInfoList!=null && playInfoList.size() > 0) {
                GetPlayInfoResponse.PlayInfo playInfo = playInfoList.get(0);
                map.put("url", playInfo.getPlayURL());
                map.put("coverurl", response.getVideoBase().getCoverURL());
            }
        } catch (Exception e) {
            map.put("message", e.getLocalizedMessage());
        }
        return tmpURL + "UploadVodPlay.html";
    }
    
    /**
     * @Description: 获取上传视频凭证和地址
     * @param req
     * @return
     */
    @Log(title = "获取上传凭证", businessType = BusinessType.OTHER)
    @GetMapping(value = "getvodauth")
    @ResponseBody
    public InterfaceResult<Map<String, Object>> uploadVideoAuth(HttpServletRequest req){
        InterfaceResult<Map<String, Object>> result = new InterfaceResult<Map<String,Object>>();
        Map<String, Object> resultMap = new HashMap<String, Object>();
        String fileName = req.getParameter("fileName");
        String title = req.getParameter("title");
        try {
            CreateUploadVideoResponse res = AliyunCommonUtil.createUploadVideo(client, fileName, title);
            resultMap.put("uploadAuth", res.getUploadAuth());
            resultMap.put("uploadAddress", res.getUploadAddress());
            resultMap.put("videoId", res.getVideoId());
            result.setResult(resultMap);
            result.setMsg("授权信息获取成功！");
        } catch (ClientException e) {
            e.printStackTrace();
            result.setError("授权信息获取失败！失败原因："+e.getMessage());
        }
        return result;
    }
    
    /**
     * @Description: 刷新上传视频凭证和地址
     * @param req
     * @return
     */
    @Log(title = "刷新上传凭证", businessType = BusinessType.OTHER)
    @GetMapping(value = "refreshvodauth")
    @ResponseBody
    public InterfaceResult<Map<String, Object>> refreshVideoAuth(HttpServletRequest req){
        InterfaceResult<Map<String, Object>> result = new InterfaceResult<Map<String,Object>>();
        Map<String, Object> resultMap = new HashMap<String, Object>();
        String videoId = req.getParameter("videoId");
        try {
            RefreshUploadVideoResponse res = AliyunCommonUtil.refreshUploadVideo(client, videoId);
            resultMap.put("uploadAuth", res.getUploadAuth());
            resultMap.put("uploadAddress", res.getUploadAddress());
            result.setResult(resultMap);
            result.setMsg("授权信息获取成功！");
        } catch (ClientException e) {
            e.printStackTrace();
            result.setError("授权信息获取失败！失败原因："+e.getMessage());
        }
        return result;
    }
    
    /**
     * 获取文件大小
     * @param size
     * @return
     */
    public static String getFormatFileSize(long size) {
          //如果字节数少于1024，则直接以B为单位，否则先除于1024，后3位因太少无意义
          if (size < 1024) {
            return String.valueOf(size) + "B";
          } else {
            size = size / 1024;
          }
          //如果原字节数除于1024之后，少于1024，则可以直接以KB作为单位
          //因为还没有到达要使用另一个单位的时候
          //接下去以此类推
          if (size < 1024) {
            return String.valueOf(size) + "KB";
          } else {
            size = size / 1024;
          }
          if (size < 1024) {
            //因为如果以MB为单位的话，要保留最后1位小数，
            //因此，把此数乘以100之后再取余
            size = size * 100;
            return String.valueOf((size / 100)) + "."
                + String.valueOf((size % 100)) + "MB";
          } else {
            //否则如果要以GB为单位的，先除于1024再作同样的处理
            size = size * 100 / 1024;
            return String.valueOf((size / 100)) + "."
                + String.valueOf((size % 100)) + "GB";
          }
    }
    
    /**
     * 获取文件后缀名
     * @param fileName
     * @return
     */
    public static String getFileExtension(String fileName) {
        String fileExtension = "";
        if(!StringUtil.isEmpty(fileName) && fileName.indexOf(".") > 0) {
            fileExtension = fileName.substring(fileName.lastIndexOf("."));
        }
        return fileExtension;
    }
}